﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Store;
using System.IO;
using Lucene.Net.Index;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;

namespace LuceneWInFormDemo
{

    public class Indexer
    {
        private Lucene.Net.Store.Directory index;
        private List<FileInfo> queue = new List<FileInfo>();
        public long TimeLastAction
        { get; private set; }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="indexPath">Path to Index location</param>
        public Indexer(string indexPath)
        {
            index = FSDirectory.GetDirectory(indexPath);
        }

        /// <summary>
        /// Index a path (file or directory)
        /// </summary>
        /// <param name="dataPath">Path to what should be indexed</param>
        /// <returns></returns>
        public int Index(string dataPath, bool overWrite)
        {
            long start = DateTime.Now.Millisecond;
            queue.Clear();
            AddToQueue(dataPath);
            IndexWriter writer = new IndexWriter(index, new StandardAnalyzer(), overWrite);
            writer.SetUseCompoundFile(false);
            foreach (FileInfo file in queue)
                IndexFile(writer, file);
            int numIndexed = writer.DocCount();
            writer.Optimize();
            writer.Close();
            long end = DateTime.Now.Millisecond;
            TimeLastAction = end - start;
            return numIndexed;
        }

        /// <summary>
        /// Add File in the Path to the queue of files to index
        /// </summary>
        /// <param name="path">Path of file or directory</param>
        private void AddToQueue(string path)
        {
            FileInfo fi = new FileInfo(path);
            if (fi.Exists)
            {
                queue.Add(fi);
            }
            else
            {
                DirectoryInfo di = new DirectoryInfo(path);
                if (di.Exists)
                {
                    foreach (FileInfo f in di.GetFiles())
                        AddToQueue(f.FullName);
                    foreach (DirectoryInfo d in di.GetDirectories())
                        AddToQueue(d.FullName);
                }
            }
        }

        /// <summary>
        /// Add file to index
        /// </summary>
        /// <param name="writer">IndexWriter</param>
        /// <param name="f">File</param>
        private void IndexFile(IndexWriter writer, FileInfo f)
        {
            if (!f.Exists)
                return;
            //if (f.isHidden() || !f.exists() || !f.canRead()) {
            //return;
            //}
            //System.out.println("Indexing " + f.getCanonicalPath());
            Document doc = new Document();
            StreamReader tr = f.OpenText();
            doc.Add(new Field("contents", tr));
            doc.Add(new Field("filename", f.FullName, Field.Store.YES, Field.Index.NOT_ANALYZED));
            writer.AddDocument(doc);
            tr.Close();
        }
    }
}